package user_controller

import (
	"encoding/json"
	"fmt"
	"github.com/gin-gonic/gin"
	"html/template"
	"net/http"
	dls "pear-admin-layui-go/app/sys/dict_list/service"
	rs "pear-admin-layui-go/app/sys/role/service"
	ud "pear-admin-layui-go/app/sys/user/domain"
	us "pear-admin-layui-go/app/sys/user/service"
	urd "pear-admin-layui-go/app/sys/user_role/domain"
	urs "pear-admin-layui-go/app/sys/user_role/service"
	"pear-admin-layui-go/framework/login_filter"
	fr "pear-admin-layui-go/framework/result"
	ft "pear-admin-layui-go/framework/table"
	"strconv"
	"time"
)

func UserRoleEdit(c *gin.Context) {
	var urer ud.UserRoleEditRquest
	_ = c.ShouldBind(&urer)
	user, _ := login_filter.GetCurrentUser(c)
	urer.UpdateTime = time.Now().Unix()
	urer.UpdateBy = user.Id
	urer.UpdateName = user.Username
	db := urs.UserRoleEdit(&urer)
	fr.Result(c, db)
}

func UserRoleSave(c *gin.Context) {
	id, _ := strconv.ParseInt(c.PostForm("id"), 10, 64)
	roleIds := c.PostFormArray("roleIds[]")
	userRoles := make([]urd.UserRole, len(roleIds))
	user, _ := login_filter.GetCurrentUser(c)
	for i, v := range roleIds {
		roleId, _ := strconv.ParseInt(v, 10, 64)
		userRoles[i] = urd.UserRole{UserId: id, RoleId: roleId, CreateTime: time.Now().Unix(), CreateBy: user.Id, CreateName: user.Username}
	}
	success, count := urs.UserRoleSave(userRoles)
	r := fr.ROk
	r.Msg = fmt.Sprintf("success = %v, count = %v, diff = %v", success, count, count-success)
	c.JSON(http.StatusOK, r)
}

func RoleEdit(c *gin.Context) {
	id, _ := strconv.ParseInt(c.Param("id"), 10, 64)
	roles := rs.UserRoles(id)
	c.HTML(http.StatusOK, "sys/user/role.html", gin.H{
		"roles": roles,
		"id":    id,
	})
}

func EditPage(c *gin.Context) {
	id, _ := strconv.ParseInt(c.Param("id"), 10, 64)
	user := us.EditPage(id)
	dlcr := dls.DictListCode("user_sex")
	c.HTML(http.StatusOK, "sys/user/edit.html", gin.H{
		"dlcr":     dlcr,
		"id":       user.Id,
		"username": user.Username,
		"realName": user.RealName,
		"nickName": user.NickName,
		"phone":    user.Phone,
		"sex":      strconv.Itoa(user.Sex),
		"email":    user.Email,
		"remark":   user.Remark,
	})
}

func Enable(c *gin.Context) {
	var uer ud.UserEnableRequest
	_ = c.ShouldBind(&uer)
	user, _ := login_filter.GetCurrentUser(c)
	uer.UpdateTime = time.Now().Unix()
	uer.UpdateBy = user.Id
	uer.UpdateName = user.Username
	db := us.Enable(&uer)
	fr.Result(c, db)
}

func AddPage(c *gin.Context) {
	dlcr := dls.DictListCode("user_sex")
	c.HTML(http.StatusOK, "sys/user/add.html", gin.H{
		"dlcr": dlcr,
	})
}

func UserEdit(c *gin.Context) {
	var uer ud.UserEditRequest
	_ = c.ShouldBind(&uer)
	user, _ := login_filter.GetCurrentUser(c)
	uer.UpdateTime = time.Now().Unix()
	uer.UpdateBy = user.Id
	uer.UpdateName = user.Username
	result := us.UserEdit(&uer)
	fr.Result(c, result)
}

func Save(c *gin.Context) {
	var uar ud.UserSaveRequest
	_ = c.ShouldBind(&uar)
	user, _ := login_filter.GetCurrentUser(c)
	uar.CreateTime = time.Now().Unix()
	uar.CreateBy = user.Id
	uar.CreateName = user.Username
	_, e := us.Save(&uar)
	var r fr.R
	if e != nil {
		r = fr.Error()
		r.Msg = e.Error()
	} else {
		r = fr.Ok()
	}
	c.JSON(http.StatusOK, r)
}

func Table(c *gin.Context) {
	var userSearch ud.UserSearchRequest
	_ = c.ShouldBind(&userSearch)
	users, count := us.Table(userSearch)
	var userTable = make([]ud.UserTableResponse, len(users))
	for i, v := range users {
		userTable[i] = ud.UserTableResponse{
			Id:         v.Id,
			Username:   v.Username,
			RealName:   v.RealName,
			NickName:   v.NickName,
			Enable:     v.Enable,
			Phone:      v.Phone,
			Sex:        v.Sex,
			Email:      v.Email,
			Login:      v.Login,
			Remark:     v.Remark,
			CreateTime: v.CreateTime,
			CreateName: v.CreateName,
			UpdateTime: v.UpdateTime,
			UpdateName: v.UpdateName,
		}
	}
	c.JSON(http.StatusOK, ft.TableResponse{
		Count: count,
		Data:  userTable,
	})
}

func Logout(c *gin.Context) {
	login_filter.RemoveCurrentUser(c)
	fr.Result(c)
}

func Login(c *gin.Context) {
	var u ud.LoginRequest
	_ = c.ShouldBind(&u)
	var r fr.R
	var dbUser = us.Login(u)
	if dbUser.Username != "" {
		login_filter.SetCurrentUser(c, login_filter.UserSession{
			Username: dbUser.Username,
			Id:       dbUser.Id,
		})
		r = fr.Ok()
	} else {
		r = fr.Error()
		r.Msg = "username or password error"
	}
	c.JSON(http.StatusOK, r)
}

func User(c *gin.Context) {
	dlcr := dls.DictListCode("user_sex")
	dlcrJson, _ := json.Marshal(dlcr)
	c.HTML(http.StatusOK, "sys/user/user.html", gin.H{
		"enable":   template.HTML("<input type=\"checkbox\" name=\"enable\" value=\"{{d.id}}\" lay-skin=\"switch\" lay-text=\"启用|禁用\" lay-filter=\"user-enable\" {{ d.enable == true ? 'checked' : '' }}/>"),
		"dlcrJson": template.HTML(dlcrJson),
	})
}
